﻿using System.Linq;
using System.Web.Mvc;
using AutoMapper;
using KinoDB.Viewmodels.Internal.DutyRoster;
using KinoDB.Viewmodels.Internal.Film;

namespace KinoDB.Controllers
{
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Data;
    using System.Net;

    using KinoDB.Viewmodels.Internal.CreateDuty;
    using KinoDB.Viewmodels.Internal.CreateResponsibility;
    using KinoDB.Viewmodels.Internal.CreateShow;
    using KinoDB.Viewmodels.Internal.DutyManagement;
    using KinoDB.Viewmodels.Internal.ShowDetails;

    using Microsoft.Ajax.Utilities;

    using Models;

    public class InternalController : Controller
    {
        Model1Container db = new Model1Container();

        //
        // GET: /Internal/
        public ActionResult Index()
        {
            return this.View();
        }

        // Movies
        /////////////////////////////////////////////////////////

        public ActionResult MovieManagement()
        {
            return this.View(db.Filme.ToList().Select(Mapper.Map<FilmViewModel>));
        }

        //
        // GET: Internal/MovieDetails
        public ActionResult MovieDetails(int id = 0)
        {
            Film movie = db.Filme.Find(id);

            if (movie == null)
            {
                return this.HttpNotFound();
            }

            return this.View(movie);
        }

        //
        // GET: /Internal/CreateMovie
        public ActionResult CreateMovie()
        {
            return this.View();
        }

        //
        // POST: /Internal/CreateMovie
        [HttpPost]
        public ActionResult CreateMovie([Bind (Include="Id,Titel,Länge,FSK,Beschreibung")]Film movie)
        {
            if (ModelState.IsValid)
            {
                db.Filme.Add(movie);
                db.SaveChanges();
            }
            
            return this.RedirectToAction("MovieManagement");
        }

        //
        // GET: Internal/EditMovie
        public ActionResult EditMovie(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Film movie = db.Filme.Find(id);
            
            if (movie == null)
            {
                return HttpNotFound();
            }

            return View(movie);
        }

        //
        // POST: Internal/EditMovie
        [HttpPost]
        public ActionResult EditMovie(Film movie)
        {
            if (ModelState.IsValid)
            {
                db.Entry(movie).State = EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("MovieManagement");
            }

            return View(movie);
        }

        //
        // GET: Internal/DeleteMovie
        public ActionResult DeleteMovie(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Film movie = db.Filme.Find(id);

            if (movie == null)
            {
                return HttpNotFound();
            }

            return View(movie);
        }

        //
        // POST: Internal/DeleteMovie
        [HttpPost, ActionName("DeleteMovie")]
        public ActionResult DeleteMovieConfirmed(int id)
        {
            Film movie = db.Filme.Find(id);
            db.Filme.Remove(movie);
            db.SaveChanges();

            return RedirectToAction("MovieManagement");
        }

        // Stuff
        /////////////////////////////////////////////////////////

        public ActionResult StaffManagement()
        {
            return this.View(db.Mitarbeiter.ToList().Select(Mapper.Map<MitarbeiterViewModel>));
        }

        //
        // GET: Internal/CreateEmployee
        public ActionResult CreateEmployee()
        {
            return this.View();
        }

        //
        // POST: Internal/CreateEmployee
        [HttpPost]
        public ActionResult CreateEmployee([Bind (Include="Id,Name,Geburtsdatum,Adresse,Stundenlohn")]Mitarbeiter employee)
        {
            if (ModelState.IsValid)
            {
                db.Mitarbeiter.Add(employee);
                db.SaveChanges();
            }

            return this.RedirectToAction("StaffManagement");
        }

        //
        // GET: Internal/EditEmpoloyee
        public ActionResult EditEmployee(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return this.HttpNotFound();
            }

            return this.View(employee);
        }

        //
        // POST: Internal/EditEmployee
        [HttpPost]
        public ActionResult EditEmployee(Mitarbeiter employee)
        {
            if (ModelState.IsValid)
            {
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();

                return this.RedirectToAction("StaffManagement");
            }

            return this.View(employee);
        }

        //
        // GET: Internal/EmployeeDetails
        public ActionResult EmployeeDetails(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return this.HttpNotFound();
            }

            return this.View(employee);
        }

        //
        // GET: Internal/DeleteEmployee
        public ActionResult DeleteEmployee(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return HttpNotFound();
            }

            return View(employee);
        }

        //
        // POST: Internal/DeleteMovie
        [HttpPost, ActionName("DeleteEmployee")]
        public ActionResult DeleteEmployeeConfirmed(int id)
        {
            Mitarbeiter employee = db.Mitarbeiter.Find(id);
            db.Mitarbeiter.Remove(employee);
            db.SaveChanges();

            return RedirectToAction("StaffManagement");
        }

        // Duty Management
        /////////////////////////////////////////////////////////

        //
        // GET: Internal/DutyManagement
        public ActionResult DutyManagement()
        {
            return this.View(db.Mitarbeiter.ToList().Select(Mapper.Map<DutyManagementViewModel>));
        }


        // TODO: rework the view model and view of duty management (create)


        //
        // GET: Internal/CreateDuty
        public ActionResult CreateDuty(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return HttpNotFound();
            }

            //CreateDutyViewModel viewModel = Mapper.Map<CreateDutyViewModel>(employee);
            CreateDutyViewModel viewModel = new CreateDutyViewModel
                                            {
                                                Id = employee.Id,
                                                Name = employee.Name
                                            };

            return this.View(viewModel);
        }

        //
        // POST: Internal/CreateDuty
        [HttpPost]
        public ActionResult CreateDuty(CreateDutyViewModel viewModel)
        {
            Mitarbeiter employee = db.Mitarbeiter.Find(viewModel.Id);

            if (employee == null)
            {
                return this.HttpNotFound();
            }

            if (ModelState.IsValid)
            {
                Dienst duty = new Dienst { Startzeit = viewModel.StartTime, Endzeit = viewModel.StartTime.AddHours(viewModel.Duration), Mitarbeiter = employee };

                db.Dienste.Add(duty);
                db.SaveChanges();

                return RedirectToAction("DutyManagement");
            }

            return this.View(viewModel);
        }

        //
        // GET: Internal/DutyRoster
        public ActionResult DutyRoster(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return HttpNotFound();
            }

            DutyRosterViewModel viewModel = Mapper.Map<DutyRosterViewModel>(employee);
            viewModel.Dienst = viewModel.Dienst.Where(x => x.Startzeit.Date >= System.DateTime.Today && x.Startzeit <= System.DateTime.Today.AddDays(5)).ToList();

            return this.View(viewModel);
        }

        // TODO: Add HttpPost Request for DutyRoster



        // Room Management
        /////////////////////////////////////////////////////////

        public ActionResult RoomManagement()
        {
            return this.View(db.Kinosäle);
        }

        //
        // GET: Internal/CreateRoom
        public ActionResult CreateRoom()
        {
            return this.View();
        }

        //
        // POST: Internal/CreateRoom
        [HttpPost]
        public ActionResult CreateRoom(Kinosaal room)
        {
            if (ModelState.IsValid)
            {
                db.Kinosäle.Add(room);
                db.SaveChanges();

                return this.RedirectToAction("RoomManagement");
            }

            return this.View(room);
        }

        //
        // GET: Internal/EditRoom
        public ActionResult EditRoom(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Kinosaal room = db.Kinosäle.Find(id);

            if (room == null)
            {
                return this.HttpNotFound();
            }

            return this.View(room);
        }

        //
        // POST: Internal/EditRoom
        [HttpPost]
        public ActionResult EditRoom(Kinosaal room)
        {
            if (ModelState.IsValid)
            {
                db.Entry(room).State = EntityState.Modified;
                db.SaveChanges();

                return this.RedirectToAction("RoomManagement");
            }

            return this.View(room);
        }

        //
        // GET: Internal/DeleteRoom
        public ActionResult DeleteRoom(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Kinosaal room = db.Kinosäle.Find(id);

            if (room == null)
            {
                return this.HttpNotFound();
            }

            return this.View(room);
        }

        //
        // POST: Internal/DeleteMovie
        [HttpPost, ActionName("DeleteRoom")]
        public ActionResult DeleteRoomConfirmed(int id)
        {
            Kinosaal room = db.Kinosäle.Find(id);
            db.Kinosäle.Remove(room);
            db.SaveChanges();

            return RedirectToAction("RoomManagement");
        }

        //
        //  GET: Internal/CreateResponsibility
        public ActionResult CreateResponsibility(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Mitarbeiter employee = db.Mitarbeiter.Find(id);

            if (employee == null)
            {
                return this.HttpNotFound();
            }

            CreateResponsibilityViewModel viewModel = Mapper.Map<CreateResponsibilityViewModel>(employee);
            
            viewModel.RoomDictionary = new Dictionary<int, string>();

            foreach (Kinosaal room in db.Kinosäle.ToList())
            {
                viewModel.RoomDictionary.Add(room.Id, room.Name);
            }

            return this.View(viewModel);
        }

        // 
        // POST: Interal/CreateResponsibility
        [HttpPost]
        public ActionResult CreateResponsibility(CreateResponsibilityViewModel viewModel)
        {
            Mitarbeiter employee = db.Mitarbeiter.Find(viewModel.Id);
            employee.Kinosaal.Add(db.Kinosäle.Find(viewModel.Selection));

            if (TryValidateModel(employee))
            {
                db.Entry(employee).State = EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction("DutyManagement");
            }

            return this.View(viewModel);
        }

        // Show Management
        /////////////////////////////////////////////////////////

        //
        // GET: Internal/ShowManagement
        public ActionResult ShowManagement()
        {
            return this.View(db.Vorstellungen);
        }

        //
        // GET: Internal/CreateShow
        public ActionResult CreateShow()
        {
            CreateShowViewModel viewModel = new CreateShowViewModel
                                            {
                                                MovieDictionary = new Dictionary<int, string>(),
                                                RoomDictionary = new Dictionary<int, string>()
                                            };

            foreach (Kinosaal room in db.Kinosäle.ToList())
            {
                viewModel.RoomDictionary.Add(room.Id, room.Name);
            }

            foreach (Film movie in db.Filme.ToList())
            {
                viewModel.MovieDictionary.Add(movie.Id, movie.Titel);
            }

            return this.View(viewModel);
        }

        //
        // POST: Internal/CreateShow
        [HttpPost]
        public ActionResult CreateShow(CreateShowViewModel viewModel)
        {
            if (ModelState.IsValid)
            {
                Vorstellung show = new Vorstellung
                {
                    Film = db.Filme.Find(viewModel.SelectedMovie),
                    Kinosaal = db.Kinosäle.Find(viewModel.SelectedRoom),
                    Startzeit = viewModel.Startzeit,
                    Kartenpreis = viewModel.Kartenpreis,
                    Kauf = new Collection<Kauf>()
                };

                db.Vorstellungen.Add(show);
                db.SaveChanges();

                RedirectToAction("ShowManagement");
            }

            return this.View(viewModel);
        }

        //
        // GET: Internal/ShowManagement
        public ActionResult ShowDetails(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Vorstellung show = db.Vorstellungen.Find(id);

            if (show == null)
            {
                return this.HttpNotFound();
            }

            ShowDetailsViewModel viewModel = new ShowDetailsViewModel
                                             {
                                                 Kartenpreis = show.Kartenpreis,
                                                 Startzeit = show.Startzeit,
                                                 Movie = show.Film.Titel,
                                                 Room = show.Kinosaal.Name,
                                                 FreeSeats =
                                                     show.Kinosaal.Sitzplatzzahl
                                                     - show.Kauf.Sum(x => x.Platzanzahl)
                                             };

            return this.View(viewModel);
        }

        //
        // GET: Internal/DeleteShow
        public ActionResult DeleteShow(int? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            Vorstellung show = db.Vorstellungen.Find(id);

            if (show == null)
            {
                return this.HttpNotFound();
            }

            return this.View(show);
        }

        //
        // POST: Internal/DeleteShow
        [HttpPost]
        [ActionName("DeleteShow")]
        public ActionResult DeleteShowConfirmed(int id)
        {
            Vorstellung show = db.Vorstellungen.Find(id);
            db.Vorstellungen.Remove(show);
            db.SaveChanges();

            return RedirectToAction("ShowManagement");
        }
    }
}